package cn.rocksolid.sport.common.utils;

import cn.rocksolid.sport.common.Constant.Symbol;
import cn.rocksolid.sport.common.error.RSE;
import cn.rocksolid.sport.common.error.RockSolidException;
import freemarker.cache.ClassTemplateLoader;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateExceptionHandler;
import org.apache.commons.lang3.StringUtils;

import java.io.StringWriter;
import java.io.Writer;
import java.nio.charset.StandardCharsets;

public class FreeMarkerUtils {

  private static final String DUMMY_TEMPLATE_PREFIX = "RST_FM_T_";

  private static Configuration freemarkerConfig = null;

  private FreeMarkerUtils() {
  }

  private static Configuration getConfig() {
    if (null == freemarkerConfig) {
      freemarkerConfig = new Configuration(Configuration.VERSION_2_3_27);
      freemarkerConfig.setDefaultEncoding(StandardCharsets.UTF_8.name());
      freemarkerConfig.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
      freemarkerConfig.setLogTemplateExceptions(false);
      freemarkerConfig.setWrapUncheckedExceptions(true);
      freemarkerConfig.setTemplateLoader(new ClassTemplateLoader(FreeMarkerUtils.class, "/ftl"));
    }
    return freemarkerConfig;
  }

  public static Template loadTemplate(final String templateName) {
    try {
      return getConfig().getTemplate(templateName);
    } catch (Exception exp) {
      throw new RockSolidException(RSE.FTL_PROCESS_ERR, exp);
    }
  }

  public static String processing(final Template template, final Object params) {
    try {
      Writer stringOutputWriter = new StringWriter();
      template.process(params, stringOutputWriter);
      return stringOutputWriter.toString();
    } catch (Exception exp) {
      throw new RockSolidException(RSE.FTL_PROCESS_ERR, exp);
    }
  }

  public static String processing(final String dummyTemplate, final Object params) {
    if (StringUtils.isBlank(dummyTemplate)) {
      return Symbol.EMPTY;
    }
    try {
      return processing(new Template(DUMMY_TEMPLATE_PREFIX + Guid.random(), dummyTemplate, getConfig()), params);
    } catch (Exception exp) {
      throw new RockSolidException(RSE.FTL_PROCESS_ERR, exp);
    }
  }
}
